﻿namespace Config
{
	using System;
	using UnityEngine;
	using System.IO;
	using System.Collections;
	using System.Collections.Generic;
	using System.Security;
	using Mono.Xml;
	using System.Linq;
	using CxExtension;
	using Table = System.Collections.Generic.Dictionary<string,string>;
	public class ConfigManager:SingletonObject<ConfigManager>
	{
		private static Dictionary<Type,Dictionary<string,BaseConfig>> tables = new Dictionary<Type,Dictionary<string,BaseConfig>>();
		public string path = "Configs/Xml";
		private const string classKey = "classKey";
		private List<string> files;
		// Use this for initialization
		public void Load()
		{
			TextAsset[] texts = Resources.LoadAll<TextAsset>(path);
			files = new List<string>(texts.Length);
			foreach(var item in texts)
			{
				files.Add(item.text);
				Resources.UnloadAsset(item);
			}
			foreach(var item in files)
			{
				ParseToInstances(item);
			}
		}
		/// <summary>
		/// 读取path路径指向的xml配置表并解析成T类型列表
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="path"></param>
		/// <returns></returns>
		public List<T> Load<T>(string path) where T : BaseConfig
		{
			var textAsset = Resources.Load<TextAsset>(path);
            if (!textAsset)
            {
                Debug.LogErrorFormat("没有读取到文件:{0}" ,path);
                return null;
            }
			var text = textAsset.text;
			var list = ParseToInstances<T>(text);
			Resources.UnloadAsset(textAsset);
			return list;
		}
		public List<T> LoadResourceConfig<T>(string path) where T : BaseConfig
		{
			var t = Load<T>("Configs/" + path);
			return t;
		}
		public List<T> LoadResourceLevelCollider<T>(string path) where T : BaseConfig
		{
			var t = Load<T>("Configs/LevelColliderConfigs/" + path);
			return t;
		}
		public void ParseToInstances(string text)
		{
			var v = ParseElement(text);//AppDomain.CurrentDomain.GetAssemblies().SelectMany
									   //v.ConvertAll<BaseConfig>()
			foreach(var i1 in v)
			{
				ParseToInstance(i1);
			}
		}
		public List<T> ParseToInstances<T>(string text) where T : BaseConfig
		{
			var v = ParseElement(text);
			var list = v.ConvertAll<T>(ParseToInstance<T>);
			return list;
		}
		public T ParseToInstance<T>(Table map) where T : BaseConfig
		{
			var classname = map[classKey];
			var obj = typeof(BaseConfig).GetSubInstanceByName(classname);
			if(obj != null)
			{
				var cof = obj as T;
				cof.Parse(map);
				return cof;
			}
			return null;
		}
		public BaseConfig ParseToInstance(Table map)
		{
			var classname = map[classKey];
			var obj = typeof(BaseConfig).GetSubInstanceByName(classname);
			if(obj != null)
			{
				var cof = obj as BaseConfig;
				cof.Parse(map);
				return cof;
			}
			return null;
		}
		public List<Table> ParseElement(string item)
		{
			var insMap = new List<Table>();
			var securityParser = new SecurityParser();
			securityParser.LoadXml(item);
			var xml = securityParser.ToXml();
			foreach(var it in xml.Children)
			{
				var node = it as SecurityElement;
				var map = ParseElement(node);
				insMap.Add(map);
			}
			return insMap;
		}
		public Table ParseElement(SecurityElement elem)
		{
			var map = new Table();
			map[classKey] = elem.Tag;
			/*foreach(var item in elem.Children)
			{
				var se = item as SecurityElement;
				var key = se.Tag;
				var value = se.Attributes["value"].ToString();
				map[key] = value;
			}*/
			foreach(DictionaryEntry item in elem.Attributes)
			{
				map[item.Key.ToString()] = item.Value.ToString();
				//map.Add()
			}
			return map;
		}
	}
}
